package com.foryou.wechat.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.foryou.wechat.common.Constants;
import com.foryou.wechat.common.enums.CapacityEnum;
import com.foryou.wechat.common.enums.ChargingModelEnum;
import com.foryou.wechat.common.enums.ImageTypeEnum;
import com.foryou.wechat.common.enums.ShootTypeEnum;
import com.foryou.wechat.entity.*;
import com.foryou.wechat.mapper.ShootCollectMapper;
import com.foryou.wechat.mapper.ShootMapper;
import com.foryou.wechat.mapper.SubjectMapper;
import com.foryou.wechat.mapper.UserMapper;
import com.foryou.wechat.model.Query;
import com.foryou.wechat.model.dto.ShootDTO;
import com.foryou.wechat.model.vo.MyShootItemVo;
import com.foryou.wechat.model.vo.ShootActionVo;
import com.foryou.wechat.model.vo.ShootVo;
import com.foryou.wechat.model.vo.UserVo;
import com.foryou.wechat.service.ShootService;
import com.foryou.wechat.service.UserFollowService;
import com.foryou.wechat.service.UserImageService;
import com.foryou.wechat.service.UserService;
import com.foryou.wechat.utils.EnumUtil;
import com.foryou.wechat.utils.HttpContextUtils;
import com.foryou.wechat.utils.RelativeDateFormat;
import com.foryou.wechat.utils.Response;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * Created by Lee.
 */
@Service
public class ShootServiceImpl implements ShootService {

    private final ShootMapper shootMapper;

    private final UserImageService imageService;

    private final UserFollowService userFollowService;

    private final ShootCollectMapper shootCollectMapper;

    private final SubjectMapper subjectMapper;

    private final UserService userService;

    public ShootServiceImpl(ShootMapper shootMapper, UserImageService imageService, UserFollowService userFollowService, ShootCollectMapper shootCollectMapper, SubjectMapper subjectMapper, UserService userService) {
        this.shootMapper = shootMapper;
        this.imageService = imageService;
        this.userFollowService = userFollowService;
        this.shootCollectMapper = shootCollectMapper;
        this.subjectMapper = subjectMapper;
        this.userService = userService;
    }

    @Override
    public int getUserShootCount(Long userId) {
        return shootMapper.selectCount(new QueryWrapper<ShootEntity>().eq("user_id", userId));
    }

    @Override
    @Transactional
    public Response addShoot(ShootDTO shootDTO) {

        //session获取userId
        Long userId = HttpContextUtils.getUserId();
        boolean checkResult = userService.checkUserInfo(userId);
        if (!checkResult) {
            return Response.failure(Constants.EDIT_USER_INFO);
        }
        ShootEntity shootEntity = new ShootEntity(
                shootDTO.getShootType(),
                shootDTO.getRequirement(),
                shootDTO.getChargingModel(),
                shootDTO.getRegion(),
                shootDTO.getShootTime(),
                shootDTO.getShootAddress(),
                shootDTO.getShootFile(),
                shootDTO.getSubjectIds(),
                userId,
                shootDTO.getPrice()
        );

        int result = shootMapper.insert(shootEntity);
        if (result > 0) {
            return Response.success(shootEntity.getId());
        }
        return Response.failure(Constants.OPERATION_FAILURE);
    }

    @Override
    public Response getUserShootList(int start,Long userId) {
        List<ShootEntity> shootList = shootMapper.getUserShootList(start, userId);
        List<MyShootItemVo> items = new ArrayList<>();
        shootList.forEach(e->{
            //得到每一个图片集合
            List<String> imageUrlList = imageService.imageUrlList(e.getId(), ImageTypeEnum.SHOOT);
            String time = RelativeDateFormat.format(e.getCreateTime());
            items.add(new MyShootItemVo(
                    e.getId(),
                    EnumUtil.getEnumByCode(ShootTypeEnum.class,e.getType()),
                    EnumUtil.getEnumByCode(ChargingModelEnum.class,e.getChargingModel()),
                    e.getShootFile(),
                    time,
                    e.getRequirement(),
                    imageUrlList
            ));
        });
        return Response.success(items);
    }

    @Override
    public Response getShootDetailById(Long shootId) {

        //TODO
        Long sessionUserId = HttpContextUtils.getUserId();
        //1.查询约拍信息
        ShootEntity shootEntity = shootMapper.selectById(shootId);
        //3.查询图片集合URL
        List<String> imageList = imageService.imageUrlList(shootId, ImageTypeEnum.SHOOT);

        boolean isOwner = shootEntity.getUserId().equals(HttpContextUtils.getUserId());

        //组装用户信息
        UserVo userVo = userFollowService.getUserVo(shootEntity.getUserId());

        //5.查询是否已经收藏该作品
        ShootCollectEntity shootCollectEntity = shootCollectMapper.selectOne(new QueryWrapper<ShootCollectEntity>()
                .eq("shoot_id", shootEntity.getId())
                .eq("user_id", sessionUserId)
        );
        boolean isCollect = !ObjectUtils.isEmpty(shootCollectEntity);
        //6.主题信息数据
        List<String> subjectList = subjectMapper.getSubjectList(shootEntity.getSubjectIds().split(","));
        return Response.success(new ShootVo(
                shootEntity.getId(),
                shootEntity.getShootTime(),
                shootEntity.getRegion().split(" ")[1],
                imageList,
                EnumUtil.getEnumByCode(ShootTypeEnum.class,shootEntity.getType()),
                EnumUtil.getEnumByCode(ChargingModelEnum.class,shootEntity.getChargingModel()),
                shootEntity.getRequirement(),
                shootEntity.getPrice(),
                subjectList,
                isCollect,
                userVo,
                DateFormatUtils.format(shootEntity.getCreateTime(), Constants.DATE_FORMAT_PATTERN_CH),
                isOwner,
                shootEntity.getScore(),
                shootEntity.getAuditStatus()
                )
        );
    }

    @Override
    public Response getShootList(Query query) {
        List<ShootActionVo> shootActionVoList = shootMapper.queryShootList(query);
        shootActionListHandler(shootActionVoList);
        return Response.success(shootActionVoList);
    }

    @Override
    public Response getIsFollowShootList(Query query) {
        Long userId = HttpContextUtils.getUserId();
        query.setUserId(userId);
        List<ShootActionVo> shootActionVoList = shootMapper.queryUserIsFollowList(query);
        shootActionListHandler(shootActionVoList);
        return Response.success(shootActionVoList);
    }

    @Override
    public Response collectShoot(Long shootId) {
        shootCollectMapper.insert(new ShootCollectEntity(shootId, HttpContextUtils.getUserId()));
        return Response.success();
    }

    @Override
    public Response cancelShoot(Long shootId) {
        shootCollectMapper.deleteShootClock(shootId, HttpContextUtils.getUserId());
        return Response.success();
    }

    @Override
    public Response queryCollectShootList(int start, Long userId) {
        List<ShootActionVo> shootActionVoList = shootMapper.queryCollectShootList(start, userId);
        shootActionListHandler(shootActionVoList);
        return Response.success(shootActionVoList);
    }

    private void shootActionListHandler(List<ShootActionVo> shootActionVoList) {
        shootActionVoList.forEach(e->{
            e.setProvince(e.getProvince().split(" ")[1]);
            e.setCapacity(EnumUtil.getEnumByCode(CapacityEnum.class, Integer.valueOf(e.getCapacity())));
            e.setImageUrlList(imageService.imageUrlList(e.getBusinessId(), ImageTypeEnum.SHOOT));
            e.setSubjectList(subjectMapper.getSubjectList(e.getSubjectIds().split(",")));
            e.setChargingModel(EnumUtil.getEnumByCode(ChargingModelEnum.class, Integer.valueOf(e.getChargingModel())));
            e.setShootType(EnumUtil.getEnumByCode(ShootTypeEnum.class, Integer.valueOf(e.getShootType())));
            e.setTime(RelativeDateFormat.format(e.getCreateTime()));
        });
    }
}
